/*
 * vim:et sts=4 sw=4 cindent:
 * $Id$
 */

import com.stamen.data.Hash
import com.stamen.utils.XMLExt;

import mx.utils.Delegate;

class com.digg.fdk.controller.ConfigLoader extends XMLExt
{
    public var config:Hash;
    public var defaults:Object;

	public function ConfigLoader(defaults:Object)
	{
	    super();
	    if (defaults != null) this.defaults = defaults;
	}

	public function onLoad(success:Boolean):Void
	{
	    if (!success)
	    {
	        this.dispatchEvent({type: 'error',
	                            message: 'unable to load url: ' + this.url});
	        return;
	    }

        this.loading = false;
	    var root:XMLNode = this.firstChild;
	    this.config = this.parseConfig(root, this.defaults);
	    this.dispatchEvent({type: EVENT_LOADED, config: this.config});
	}

	public function parseConfig(node:XMLNode, defaults:Object)
	{
        var obj:Hash, arr:Array, isArray:Boolean;
        if (node.attributes['type'] == 'array')
        {
            arr = new Array();
            isArray = true;
        }
        else
        {
            obj = new Hash(defaults);
            isArray = false;
        }
        for (var child:XMLNode = node.firstChild; child; child = child.nextSibling)
        {
            var keyName:String = child.attributes['name'];
            var value = null;

            if (!keyName && !isArray)
            {
                trace("ConfigLoader.parseConfig(): couldn't find name attribute in: " + child.toString());
                continue;
            }

            if (child.childNodes.length > 0 && child.firstChild.nodeType != 3)
            {
                value = this.parseConfig(child);
            }
            else
            {
                var str:String = (child.firstChild.nodeType == 3)
                                 ? child.firstChild.nodeValue
                                 : child.attributes['value'];
                if (null == str)
                {
                    trace("ConfigLoader.parseConfig(): couldn't find value in: " + child.toString());
                    continue;
                }
            
                var type:String = child.attributes['type'];
                // trace('ConfigLoader.parseConfig(): checking value "' + str + '", type "' + type + '"');
                switch (type)
                {
                    case 'int':
                        value = parseInt(str);
                        break;

                    case 'number':
                    case 'float':
                        value = parseFloat(str);
                        break;

                    case 'bool':
                        value = (parseInt(str) != 0 && str != 'false');
                        break;

                    case 'string':
                    default:
                        if (str == 'null') value = null;
                        else value = str;
                }
            }

            if (isArray)
            {
                arr.push(value);
            }
            else
            {
                // trace('ConfigLoader.parseConfig(): setting keyName "' + keyName + '" to value: ' + value + ' (type: ' + typeof value + ')');
                obj.setValue(keyName, value);
            }
        }

		return isArray ? arr : obj;
	}
	
	public function setValue(keyName:String, value:Object):Object
	{
	    return this.config.setValue(keyName, value);
	}
	
	public function getValue(keyName:String):Object
	{
	    return this.config.getValue(keyName);
	}
}
